package com.tuniu.agents.impl.trip;

import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.beans.factory.annotation.Autowired;

import com.tuniu.agents.advisor.ChatEnvironmentMemory;
import com.tuniu.agents.agent.AgentManagerGroup;
import com.tuniu.agents.common.agent.TripAgent;
import com.tuniu.agents.common.client.OpenAIHttpClient;
import com.tuniu.agents.common.entity.trip.ExtractResourceResponse;
import com.tuniu.agents.common.entity.trip.TripSummary;
import com.tuniu.agents.memory.MemoryManager;
import com.tuniu.agents.message.MessageLogger;
import com.tuniu.agents.message.MessageSender;
import com.tuniu.agents.util.HttpManager;
import com.tuniu.agents.util.JsonUtil;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

@Slf4j
public class Extractor extends TripAgent {
    public static final String TRIP_SUMMARY = "tripSummary"; // Trip Summary Key
    public static final String TRIP_RESOURCE_LIST = "tripResourceList"; // Resource List Key

    @Value("${aigc.agents.tools.trip.tripAgentResourceUrl}")
    private String RESOURCE_URL;

    private static final String IMAGE_PROMPT = "Please analyze the content of this image.";
    private static final String TEXT_PROMPT = "Please analyze the content of this document.";
    private static final String SYSTEM_PROMPT = """
                 # Role
   You are a professional travel expert. Analyze the provided travel-related image/document in detail. and generate:
   1. Concise bullet points with key tourism insights.
   2. Trip summary
   - Summarize in one sentence
   3. Resource list
   - traffic, hotel and attractions(poi), names only
# Format
   - use {{common.prompt.use.language}}
   - output in strict json format
   ## example
    {
      "tourismPoint":" ",
      "tripSummary": " ",
      "resourceList": {
        "hotel": [],
        "poi": []
      }
    }

            """;


    @Autowired
    private ChatEnvironmentMemory chatEnvironmentMemory;
    @Autowired
    private OpenAIHttpClient openAiHttpClient;

    @Autowired
    private HttpManager httpManager;
    
    private MemoryManager memoryManager;

    @Autowired
    private MessageSender messageSender;
    public Extractor(AgentManagerGroup agentManagerGroup,
                            String agentId, MessageSender messageSender,String promptTemplateId,MessageLogger messageLogger, ChatOptions chatOptions) {
        super(agentManagerGroup, agentId, promptTemplateId,messageLogger,chatOptions);
        this.memoryManager = agentManagerGroup.getMemoryManager();

    }

    @Override
    public String call(String conversationId, List<Message> messages, Map<String, Object> context) {
        String message = messages.get(0).getText();
        messageSender.send(conversationId, "Analyzing your trip information...");
        String content = parseContent(message);
        // Parse trip summary
        TripSummary tripSummary = getTripSummary(content);
        ExtractResourceResponse.Data extractResourceData = getResourceString(tripSummary); // Extracted resource information
        // Add trip content to global variables
        chatEnvironmentMemory.add(conversationId, Map.of(TRIP_SUMMARY, tripSummary));
        chatEnvironmentMemory.add(conversationId, Map.of(TRIP_RESOURCE_LIST, extractResourceData));

        memoryManager.setMessageRight(conversationId, Collections.singletonList(new AssistantMessage(tripSummary.getTripSummary(), Map.of("agentId", TripAgentConfig.EXTRACTOR_AGENT_ID))));
        return extractResourceData.toMarkdown();
    }
    

    private String parseContent(String message) {
        String content = "";
        try {
            // Check if it's a Base64 encoded image
            if (isBase64Image(message)) {
                log.info("Processing image content");
                content = openAiHttpClient.sendRequestForImage(SYSTEM_PROMPT, IMAGE_PROMPT, message, null);
            }else{
                // Process as plain text
                log.info("Processing text content");
                content = openAiHttpClient.sendRequest(
                    SYSTEM_PROMPT,
                    TEXT_PROMPT+"\n" + message,
                    "qwen2.5-32b-instruct"
                );
            }
            
           
        } catch (Exception e) {
            log.error("Failed to parse document content", e);
            throw new RuntimeException("Failed to parse document content", e);
        }
        log.info("Parsed content: {}", content);
        return content;
    }

    /**
     * Parse trip information returned by the model
     */
    private TripSummary getTripSummary(String content){
        if(StringUtils.isBlank(content)){
            return null;
        }
        TripSummary tripSummary = new TripSummary();
        
        // Extract JSON data using regex pattern
        String jsonPattern = "\\{.*\\}";
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(jsonPattern, java.util.regex.Pattern.DOTALL);
        java.util.regex.Matcher matcher = pattern.matcher(content);
        
        if (matcher.find()) {
            String jsonString = matcher.group(0);
            log.info("Preparing to parse trip information returned by model, {}", jsonString);
            try {
                // Clean special characters in JSON string
                jsonString = jsonString.trim()
                    .replaceAll("[\\x00-\\x1F\\x7F]", "") // Remove control characters
                    .replaceAll("\\uFEFF", ""); // Remove BOM mark
                tripSummary = JsonUtil.fromJson(jsonString, TripSummary.class);
                return tripSummary;
            } catch (Exception e) {
                log.error("Failed to parse trip information returned by model, original JSON: {}", jsonString, e);
            }
        } else {
            log.error("JSON data not found");
        }

        return tripSummary;
    }
    /**
     * 
     * @param tripSummary
     * @return
     */

    private ExtractResourceResponse.Data getResourceString(TripSummary tripSummary){
        log.info("Extracting resource list: {}", JsonUtil.toJson(tripSummary.getResourceList()));
        ExtractResourceResponse result = httpManager.post(RESOURCE_URL, tripSummary.getResourceList(),   ExtractResourceResponse.class);
        log.info("Resource matching result: {}", JsonUtil.toJson(result.getData()));
        return result.getData();
    }
    private boolean isBase64Image(String content) {
        try {
            byte[] decodedBytes = Base64.getDecoder().decode(content);
            // Check if it's an image format (check file header)
            if (decodedBytes.length < 4) return false;
            
            // Check common image format file headers
            return (decodedBytes[0] == (byte)0xFF && decodedBytes[1] == (byte)0xD8) || // JPEG
                   (decodedBytes[0] == (byte)0x89 && decodedBytes[1] == (byte)0x50) || // PNG
                   (decodedBytes[0] == (byte)0x47 && decodedBytes[1] == (byte)0x49);  // GIF
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
}
